package org.east.common.utils;

/**
 * 基于httpclient4.5
 * @author fund9
 *
 */
public class HttpClientUtils {
	
	
	
	
	
	
	
	/*{
		
		private static Log log = LogFactory.getLog(ReqServiceUtils.class);
		
		*//**
		 * 
		 * @param req
		 * @return
		 *//*
		public static String reqService(BaseReq req) throws ErrorCodeException,YingmiException{
			if("POST".equals(req.getHttpMethod())){
				return reqBypost(req);
			}else if("GET".equals(req.getHttpMethod())){
				return reqByGet(req);
			}else{
				throw new ErrorCodeException("0004","HTTP方法非法");
			}
		}
		
		*//**
		 * 
		 * @param req
		 * @return
		 * @throws ErrorCodeException
		 *//*
		public static String reqBypost(BaseReq req) throws ErrorCodeException,YingmiException{
			
			String ym_api_baseUrl = ConfigUtil.getPropertiesValue("ym_api_baseUrl");
			if(ym_api_baseUrl == null){
				throw new ErrorCodeException("0004","baseUrl参数未配置");
			}
			if(req.getApiPath() == null){
				throw new ErrorCodeException("0004","ApiPath参数缺失");
			}
			String url = ym_api_baseUrl + req.getApiPath();
			Map<String,String> data = req.toMap();
			log.info("url="+url);
			SignUtils.initSignData(data);
			data.remove("httpMethod");
			data.remove("apiPath");
			HttpUriRequest request;
			try {
				URIBuilder builder = new URIBuilder(url);
				URI uri = builder.build();
				RequestBuilder requestBuilder = RequestBuilder.post(uri);
				List<NameValuePair> kvs = new ArrayList<>();
	            for (String key : data.keySet()) {
	                kvs.add(new BasicNameValuePair(key, data.get(key)));
	            }
	            requestBuilder.setEntity(new UrlEncodedFormEntity(kvs, "UTF-8"));
	            request = requestBuilder.build();
			} catch (URISyntaxException e) {
				throw new ErrorCodeException("0004","Uri非法",e);
			} catch (UnsupportedEncodingException e) {
				throw new ErrorCodeException("0004","编码不支持",e);
			}
			
			//HttpClient httpClient = HttpClients.custom().build();
			HttpClient httpClient = buildHttpClient();
			String respStr = null;
			try {
				HttpResponse resp = httpClient.execute(request);
				//获取响应状态码
			    int status = resp.getStatusLine().getStatusCode(); 
			    if(status == 200){
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
			    }else if(status == 400){  //盈米定义 表示openapi的请求参数缺少必要字段
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 401){  //盈米定义 表示校验未通过，可能原因是使用了错误的api key或者签名校验失败
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 500){  //系统错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 501){ //盈米定义 业务错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else{
			    	log.error("状态码异常:"+resp.getStatusLine().toString());
		        	throw new ErrorCodeException("0003","http状态码异常");
			    }
			    
		        if (status >= 200 && status < 300) {
		            HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		        } else if(status == 504){
		        	log.error("状态码异常,网关超时:"+resp.getStatusLine().toString());
		        	throw new ErrorCodeException("0003","网关超时");
		        } else {
		        	log.error("状态码异常:"+resp.getStatusLine().toString());
		        	throw new ErrorCodeException("0003","http状态码异常");
		        }
				
			} catch (ClientProtocolException e) {
				throw new ErrorCodeException("0004","客户端协议异常",e);
			} catch (IOException e) {
				throw new ErrorCodeException("0003","IO异常",e);
			}
			
			if(respStr == null){
				throw new ErrorCodeException("0003","未收到响应消息");
			}
			return respStr;
		}
		
		*//**
		 * 
		 * @param req
		 * @return
		 * @throws ErrorCodeException
		 *//*
		public static String reqByGet(BaseReq req) throws ErrorCodeException,YingmiException {
			
			String ym_api_baseUrl = ConfigUtil.getPropertiesValue("ym_api_baseUrl");
			if(ym_api_baseUrl == null){
				throw new ErrorCodeException("0004","baseUrl参数未配置");
			}
			if(req.getApiPath() == null){
				throw new ErrorCodeException("0004","ApiPath参数缺失");
			}
			String url = ym_api_baseUrl + req.getApiPath();
			Map<String,String> data = req.toMap();
			log.info("url="+url);
			SignUtils.initSignData(data);
			data.remove("httpMethod");
			data.remove("apiPath");
			HttpGet httpGet ;
			try {
				URIBuilder builder = new URIBuilder(url);
				for (String key: data.keySet()) {
		            builder.setParameter(key, data.get(key).toString());
		        }
				URI uri = builder.build();
				httpGet = new HttpGet(uri);
			} catch (URISyntaxException e) {
				throw new ErrorCodeException("0004","Uri非法",e);
			}
			
			//HttpClient httpClient = HttpClients.custom().build();
			HttpClient httpClient = buildHttpClient();
			String respStr = null;
			try {
				HttpResponse resp = httpClient.execute(httpGet);
				//获取响应状态码
			    int status = resp.getStatusLine().getStatusCode();  
			    if(status == 200){
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
			    }else if(status == 400){  //盈米定义 表示openapi的请求参数缺少必要字段
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 401){  //盈米定义 表示校验未通过，可能原因是使用了错误的api key或者签名校验失败
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 500){  //系统错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 501){ //盈米定义 业务错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else{
			    	log.error("状态码异常:"+resp.getStatusLine().toString());
		        	throw new ErrorCodeException("0003","http状态码异常");
			    }
				
			} catch (ClientProtocolException e) {
				throw new ErrorCodeException("0004","客户端协议异常",e);
			} catch (IOException e) {
				throw new ErrorCodeException("0003","IO异常",e);
			}
			
			if(respStr == null){
				throw new ErrorCodeException("0003","未收到响应消息");
			}
			return respStr;
		}
		
		*//**
		 * 下载文件
		 * @param req
		 * @return
		 * @throws ErrorCodeException
		 * @throws YingmiException
		 *//*
		public static BaseDownloadFileResp downloadFile(BaseReq req) throws ErrorCodeException,YingmiException{
			String ym_api_fileBaseUrl = ConfigUtil.getPropertiesValue("ym_api_fileBaseUrl");
			if(ym_api_fileBaseUrl == null){
				throw new ErrorCodeException("0004","fileBaseUrl参数未配置");
			}
			if(req.getApiPath() == null){
				throw new ErrorCodeException("0004","ApiPath参数缺失");
			}
			String url = ym_api_fileBaseUrl + req.getApiPath();
			Map<String,String> data = req.toMap();
			log.info("url="+url);
			SignUtils.initSignData(data);
			data.remove("httpMethod");
			data.remove("apiPath");
			HttpGet httpGet ;
			try {
				URIBuilder builder = new URIBuilder(url);
				for (String key: data.keySet()) {
		            builder.setParameter(key, data.get(key).toString());
		        }
				URI uri = builder.build();
				httpGet = new HttpGet(uri);
			} catch (URISyntaxException e) {
				throw new ErrorCodeException("0004","Uri非法",e);
			}
			
			//HttpClient httpClient = HttpClients.custom().build();
			HttpClient httpClient = buildHttpClient();
			String respStr = null;
			try {
				HttpResponse resp = httpClient.execute(httpGet);
				//获取响应状态码
			    int status = resp.getStatusLine().getStatusCode();  
			    if(status == 200){
			    	String fileName = null;
			    	Header[] hds = resp.getHeaders("Content-Disposition");
			    	if(hds != null && hds.length > 0){
			    		Header hd = hds[0];
			    		if(hd.getElements().length >= 0){
			    			HeaderElement he = hd.getElements()[0];
			    			NameValuePair  nv = he.getParameterByName("filename");
			    			if(nv != null){
			    				fileName = nv.getValue();
			    			}
			    		}
			    	}
			    	String fileId = UUID.randomUUID().toString().replace("-", "");
			    	if(fileName == null){
			    		fileName = fileId;
			    	}
			    	String ym_api_filedown_root = ConfigUtil.getPropertiesValue("ym_api_filedown_root");
			    	if(ym_api_filedown_root == null || "".equals(ym_api_filedown_root)){
			    		throw new ErrorCodeException("0004","未配置盈米文件存放根目录");
			    	}
			    	String fileDir = ym_api_filedown_root + "/"+fileId;
			    	
			    	HttpEntity entity = resp.getEntity();
			    	InputStream in = entity.getContent();
			    	FileOutputStream fout = null;
			    	File file = null;
			    	try{
			    		log.info("下载文件="+fileDir + "/" + fileName);
			    		file = new File(fileDir + "/" + fileName);
				    	if(!file.getParentFile().exists()){
				    		file.getParentFile().mkdirs();
				    	}
			    		fout = new FileOutputStream(file);
			    		int l = -1;  
			            byte[] tmp = new byte[1024];  
			            while ((l = in.read(tmp)) != -1) {  
			                fout.write(tmp, 0, l);  
			            }
			            fout.flush();
			            //EntityUtils.consume(entity);
			    	}catch(Exception e){
			    		throw new ErrorCodeException("0004","存储文件出错",e);
			    	}finally{
			    		if(fout != null){
			    			fout.close();
			    		}
			    		if(in != null){
			    			in.close();
			    		}
			    	}
			    	
			    	//对应md5文件
			    	String md5 = downloadMd5File(req);
			    	String fileMd5 = FileUtils.getFileMD5(file);
			    	if(!fileMd5.equals(md5)){
			    		log.error("下载文件md5值不匹配文件md5="+fileMd5+",盈米md5文件="+md5);
			    	}
			    	BaseDownloadFileResp r = new BaseDownloadFileResp();
			    	r.setFile(file);
			    	r.setFileId(fileId);
			    	r.setFileMd5(fileMd5);
			    	r.setFileName(fileName);
		            return r;
			    }else if(status == 400){  //盈米定义 表示openapi的请求参数缺少必要字段
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 401){  //盈米定义 表示校验未通过，可能原因是使用了错误的api key或者签名校验失败
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 404){  //资源不存在
		            throw new ErrorCodeException("0004","资源不存在");
			    }else if(status == 500){  //系统错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 501){ //盈米定义 业务错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else{
			    	log.error("状态码异常:"+resp.getStatusLine().toString());
		        	throw new ErrorCodeException("0003","http状态码异常");
			    }
				
			} catch (ClientProtocolException e) {
				throw new ErrorCodeException("0004","客户端协议异常",e);
			} catch (IOException e) {
				throw new ErrorCodeException("0003","IO异常",e);
			}
			
		}
		
		*//**
		 * 读取相应md5文件
		 * @param req
		 * @return
		 * @throws ErrorCodeException
		 * @throws YingmiException
		 *//*
		private static String downloadMd5File(BaseReq req) throws ErrorCodeException,YingmiException{
			String ym_api_fileBaseUrl = ConfigUtil.getPropertiesValue("ym_api_fileBaseUrl");
			if(ym_api_fileBaseUrl == null){
				throw new ErrorCodeException("0004","fileBaseUrl参数未配置");
			}
			if(req.getApiPath() == null){
				throw new ErrorCodeException("0004","ApiPath参数缺失");
			}
			String url = ym_api_fileBaseUrl + req.getMd5fileApiPath();
			req.updateDateTime();
			Map<String,String> data = req.toMap();
			data.put("apiPath", req.getMd5fileApiPath());
			log.info("url="+url);
			SignUtils.initSignData(data);
			data.remove("httpMethod");
			data.remove("apiPath");
			HttpGet httpGet ;
			try {
				URIBuilder builder = new URIBuilder(url);
				for (String key: data.keySet()) {
		            builder.setParameter(key, data.get(key).toString());
		        }
				URI uri = builder.build();
				httpGet = new HttpGet(uri);
			} catch (URISyntaxException e) {
				throw new ErrorCodeException("0004","Uri非法",e);
			}
			
			//HttpClient httpClient = HttpClients.custom().build();
			HttpClient httpClient = buildHttpClient();
			String respStr = null;
			try {
				HttpResponse resp = httpClient.execute(httpGet);
				//获取响应状态码
			    int status = resp.getStatusLine().getStatusCode();  
			    if(status == 200){
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
			    }else if(status == 400){  //盈米定义 表示openapi的请求参数缺少必要字段
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 401){  //盈米定义 表示校验未通过，可能原因是使用了错误的api key或者签名校验失败
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 404){  //资源不存在
		            throw new ErrorCodeException("0004","资源不存在");
			    }else if(status == 500){  //系统错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else if(status == 501){ //盈米定义 业务错误
			    	HttpEntity entity = resp.getEntity();
		            respStr = entity != null ? EntityUtils.toString(entity, "UTF-8") : null;  
		            log.info("resp="+respStr);
		            if(respStr!=null){
		            	throw new YingmiException(status,respStr);
		            }else{
		            	throw new ErrorCodeException("0003","未收到响应消息");
		            }
			    }else{
			    	log.error("状态码异常:"+resp.getStatusLine().toString());
		        	throw new ErrorCodeException("0003","http状态码异常");
			    }
				
			} catch (ClientProtocolException e) {
				throw new ErrorCodeException("0004","客户端协议异常",e);
			} catch (IOException e) {
				throw new ErrorCodeException("0003","IO异常",e);
			}
			
			if(respStr == null){
				throw new ErrorCodeException("0004","未收到md5消息");
			}
			return respStr;
		}
		
		private static String keyStoreType = "PKCS12";
		private static SSLConnectionSocketFactory sf = null;
		
		static {
			try{
				KeyStore ks = KeyStore.getInstance(keyStoreType);
				String ym_api_keyStoreFile = ConfigUtil.getPropertiesValue("ym_api_keyStoreFile");
				String ym_api_keyStorePassword = ConfigUtil.getPropertiesValue("ym_api_keyStorePassword");
		    	ks.load(new FileInputStream(new File(ym_api_keyStoreFile)), ym_api_keyStorePassword.toCharArray());
		    	
		    	SSLContext context = SSLContexts.custom()
		    			.loadKeyMaterial(ks,ym_api_keyStorePassword.toCharArray())
		    			.build();
		    
		        sf = new SSLConnectionSocketFactory(
		                context,
		                new String[] {"TLSv1.2"},
		                null,
		                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
			}catch(KeyStoreException | NoSuchAlgorithmException | CertificateException 
					| IOException | KeyManagementException | UnrecoverableKeyException e){
				log.error("加载盈米证书异常",e);
			}
		}
		
		*//**
		 * 
		 * @return
		 *//*
		private static HttpClient buildHttpClient() throws ErrorCodeException{
			if(sf == null){
				throw new ErrorCodeException("0004","盈米证书未加载");
			}
			try{
				HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sf).build();
		        return httpClient;
			}catch(Exception e){
				throw new ErrorCodeException("0004","构建httpclient失败");
			}
		}

	}*/
	
	

}
